package com.happystudy.serviceImpl;

import com.happpystudy.model.*;
import com.happpystudy.model.course.CourseTeacher;
import com.happpystudy.service.CourseService;
import com.happpystudy.service.UserService;
import com.happystudy.mapper.EducatorInfoMapper;
import com.happystudy.mapper.LearnerInfoMapper;
import com.happystudy.mapper.UniversityMapper;
import com.happystudy.mapper.UserMapper;
import com.happystudy.util.KeyUtil;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.List;

@Service
public class UserServiceImpl implements UserService {

    final String WEB_USER_KEY="WEBUSER:";
    final String LEARNER_KEY="LEARNERINFO:";
    final String EDUCTOR_KEY="EDUCTORINFO:";
    @Resource
    UserMapper userMapper;
    @Resource
    LearnerInfoMapper learnerInfoMapper;
    @Resource
    EducatorInfoMapper educatorInfoMapper;

    @Resource
    UniversityMapper universityMapper;

    @Resource
    CourseService courseService;

    @Resource
    UserService userService;

    @Resource
    RedisTemplate redisTemplate;



    @Override
    @Transactional
    public Integer doRegister(User user) {
        //获取下一个
        redisTemplate.setKeySerializer(new StringRedisSerializer());
        String key;
        int result = 0;
        int nextUserId = userMapper.selectNextPrimaryKey();
        user.setUserId(nextUserId);
        //判断user角色
        if ("learner".equals(user.getRole())){
            LearnerInfo userInfo = new LearnerInfo();
            userInfo.setUserId(user.getUserId());
            userInfo.setMetricNo(String.format("%06d", user.getUserId()));
            userInfo.setUsername(user.getUsername());
            result = learnerInfoMapper.insertSelective(userInfo);
            redisTemplate.setValueSerializer(new Jackson2JsonRedisSerializer<LearnerInfo>(LearnerInfo.class));
            key = LEARNER_KEY+user.getUserId();
            LearnerInfo redis_userInfo = (LearnerInfo)redisTemplate.opsForValue().get(key);
            if (redis_userInfo==null){
                redisTemplate.opsForValue().set(key,userInfo);
            }

        }else if ("eductor".equals(user.getRole())){
            EducatorInfo userInfo = new EducatorInfo();
            userInfo.setUserId(user.getUserId());
            userInfo.setStaffId(String.format("%06d", user.getUserId()));
            userInfo.setUsername(user.getUsername());
            result = educatorInfoMapper.insertSelective(userInfo);
            redisTemplate.setValueSerializer(new Jackson2JsonRedisSerializer<EducatorInfo>(EducatorInfo.class));
            key = EDUCTOR_KEY+user.getUserId();
            EducatorInfo redis_userInfo = (EducatorInfo)redisTemplate.opsForValue().get(key);
            if (redis_userInfo==null){
                redisTemplate.opsForValue().set(key,userInfo);
            }
        }
        System.out.println(result);
        result = userMapper.insertSelective(user);
        System.out.println(result);
        if (result>0){
            key = WEB_USER_KEY + user.getUserId();
            redisTemplate.setValueSerializer(new Jackson2JsonRedisSerializer<User>(User.class));
            User redis_user = (User)redisTemplate.opsForValue().get(key);
            if (redis_user==null){
                redisTemplate.opsForValue().set(key,user);
            }
        }

        return result;
    }

    public User doLogin(User record){
        User user = userMapper.selectByUsernameAndPassword(record);
        if (user!=null){
            //登录成功
//            Integer userId = user.getUserId();
//            String role = user.getRole();
//            String uniId = user.getUniId();
//            University university = universityMapper.selectByPrimaryKey(uniId);
//            user.setUniversity(university);
//            UserInfo userInfo;
//            if ("learner".equals(role)){
//                userInfo = learnerInfoMapper.selectByPrimaryKey(userId);
//            }else{
//                userInfo = educatorInfoMapper.selectByPrimaryKey(userId);
//            }
//            user.setUserInfo(userInfo);
            user = userService.returnUserInfoByUserID(user.getUserId());
            return user;
        }
        return null;
    }

    @Transactional
    public int updateUserInfo(String key, String value, User recordUser){
        Integer result = 0;
        String redisKey;
        redisTemplate.setKeySerializer(new StringRedisSerializer());
        redisTemplate.setValueSerializer(new Jackson2JsonRedisSerializer<User>(User.class));
        redisKey =  WEB_USER_KEY + recordUser.getUserId();
        User redis_user = (User)redisTemplate.opsForValue().get(redisKey);
        if (redis_user==null){
            redis_user = userMapper.selectByPrimaryKey(recordUser.getUserId());
            if (redis_user!=null){
                redisTemplate.opsForValue().set(redisKey,redis_user);
            }
        }
        switch (key){
            case "name":{
                //修改姓名
                String[] nameList = value.split(" ");
                String fName = nameList[0];
                String lName = nameList[1];
                redis_user.setfName(fName);
                redis_user.setlName(lName);
                break;
            }
            case "email":{
                //修改email
                redis_user.setEmail(value);

                break;
            }
            case "telephone":{
                //修改telephone
                redis_user.setTelNo(value);
                break;
            }
            case "level":{
                //修改email
                redisKey = LEARNER_KEY+recordUser.getUserId();
                redisTemplate.setValueSerializer(new Jackson2JsonRedisSerializer<LearnerInfo>(LearnerInfo.class));
                LearnerInfo redis_userInfo = (LearnerInfo)redisTemplate.opsForValue().get(redisKey);
                if (redis_userInfo==null){
                    redis_userInfo = learnerInfoMapper.selectByPrimaryKey(recordUser.getUserId());
                    if (redis_userInfo!=null){
                        redisTemplate.opsForValue().set(redisKey,redis_userInfo);
                    }
                }
                redis_userInfo.setDiploma(value);
                result = learnerInfoMapper.updateByPrimaryKeySelective(redis_userInfo);
                if (result>0){
                    redisTemplate.opsForValue().set(redisKey,redis_userInfo);
                }
                break;
            }
            case "major":{
                redisKey = LEARNER_KEY+recordUser.getUserId();
                redisTemplate.setValueSerializer(new Jackson2JsonRedisSerializer<LearnerInfo>(LearnerInfo.class));
                LearnerInfo redis_userInfo = (LearnerInfo)redisTemplate.opsForValue().get(redisKey);
                if (redis_userInfo==null){
                    redis_userInfo = learnerInfoMapper.selectByPrimaryKey(recordUser.getUserId());
                    if (redis_userInfo!=null){
                        redisTemplate.opsForValue().set(redisKey,redis_userInfo);
                    }
                }
                redis_userInfo.setMajor(value);
                result = learnerInfoMapper.updateByPrimaryKeySelective(redis_userInfo);
                if (result>0){
                    redisTemplate.opsForValue().set(redisKey,redis_userInfo);
                }
                break;
            }
            case "staffId":{
                redisKey = EDUCTOR_KEY+recordUser.getUserId();
                redisTemplate.setValueSerializer(new Jackson2JsonRedisSerializer<>(EducatorInfo.class));
                EducatorInfo redis_userInfo = (EducatorInfo)redisTemplate.opsForValue().get(redisKey);
                if (redis_userInfo==null){
                    redis_userInfo = educatorInfoMapper.selectByPrimaryKey(recordUser.getUserId());
                    if (redis_userInfo!=null){
                        redisTemplate.opsForValue().set(redisKey,redis_userInfo);
                    }
                }
                redis_userInfo.setStaffId(value);
                result = educatorInfoMapper.updateByPrimaryKeySelective(redis_userInfo);
                if (result>0){
                    redisTemplate.opsForValue().set(redisKey,redis_userInfo);
                }
                break;

            }
            case "subject":{
                redisKey = EDUCTOR_KEY+recordUser.getUserId();
                redisTemplate.setValueSerializer(new Jackson2JsonRedisSerializer<>(EducatorInfo.class));
                EducatorInfo redis_userInfo = (EducatorInfo)redisTemplate.opsForValue().get(redisKey);
                if (redis_userInfo==null){
                    redis_userInfo = educatorInfoMapper.selectByPrimaryKey(recordUser.getUserId());
                    if (redis_userInfo!=null){
                        redisTemplate.opsForValue().set(redisKey,redis_userInfo);
                    }
                }
                redis_userInfo.setSubject(value);
                result = educatorInfoMapper.updateByPrimaryKeySelective(redis_userInfo);
                if (result>0){
                    redisTemplate.opsForValue().set(redisKey,redis_userInfo);
                }
                break;
            }
            case "levelOfJob":{
                redisKey = EDUCTOR_KEY+recordUser.getUserId();
                redisTemplate.setValueSerializer(new Jackson2JsonRedisSerializer<>(EducatorInfo.class));
                EducatorInfo redis_userInfo = (EducatorInfo)redisTemplate.opsForValue().get(redisKey);
                if (redis_userInfo==null){
                    redis_userInfo = educatorInfoMapper.selectByPrimaryKey(recordUser.getUserId());
                    if (redis_userInfo!=null){
                        redisTemplate.opsForValue().set(redisKey,redis_userInfo);
                    }
                }
                redis_userInfo.setLevelOfJob(value);
                result = educatorInfoMapper.updateByPrimaryKeySelective(redis_userInfo);
                if (result>0){
                    redisTemplate.opsForValue().set(redisKey,redis_userInfo);
                }
                break;
            }
            case "university":{
                //修改email
                University university = universityMapper.selectByUniversityName(value);
                if (university==null){
                    return -1;//代表为查找到 university
                }
                recordUser.setUniId(value);
                break;
            }

        }
        redisKey =  WEB_USER_KEY + recordUser.getUserId();
        result = userMapper.updateByPrimaryKeySelective(redis_user);
        if (result>0){
            redisTemplate.opsForValue().set(redisKey,redis_user);
        }
        return result;
    }



    public User returnCurrentInfo(User record){
        Integer userId = record.getUserId();
        String role = record.getRole();
        String redisKey =  WEB_USER_KEY + record.getUserId();
        redisTemplate.setKeySerializer(new StringRedisSerializer());
        redisTemplate.setValueSerializer(new Jackson2JsonRedisSerializer<User>(User.class));
        User user = (User) redisTemplate.opsForValue().get(redisKey);
        if (user==null){
            System.out.println("user在redis中查询到");
            user = userMapper.selectByPrimaryKey(userId);
            //这里要注意缓存击穿
            if (user!=null){
                redisTemplate.opsForValue().set(redisKey,user);
            }
        }

        if (user==null){
            return null;
        }

        UserInfo userInfo;
        if ("learner".equalsIgnoreCase(role)){
            redisKey = LEARNER_KEY+record.getUserId();
            redisTemplate.setValueSerializer(new Jackson2JsonRedisSerializer<>(LearnerInfo.class));
            userInfo = (UserInfo) redisTemplate.opsForValue().get(redisKey);
            if (userInfo==null){
                System.out.println("userinfo在redis中查询到");
                userInfo = learnerInfoMapper.selectByPrimaryKey(userId);
                if (userInfo!=null){
                    redisTemplate.opsForValue().set(redisKey,userInfo);
                }
            }

        }else {
            redisKey = EDUCTOR_KEY+record.getUserId();
            redisTemplate.setValueSerializer(new Jackson2JsonRedisSerializer<>(EducatorInfo.class));
            userInfo = (UserInfo) redisTemplate.opsForValue().get(redisKey);
            if (userInfo==null){
                userInfo = educatorInfoMapper.selectByPrimaryKey(userId);
                if (userInfo!=null){
                    redisTemplate.opsForValue().set(redisKey,userInfo);
                }
            }

        }

        List<CourseTeacher> courses = courseService.queryCoursesByUserId(userId,role);
        System.out.println(courses);


        String uniId = user.getUniId();
        University university = universityMapper.selectByPrimaryKey(uniId);
        user.setUserInfo(userInfo);
        user.setUniversity(university);
        if (courses==null){
            user.setCourses(courses);
        }
        return user;

    }

    @Transactional
    public User returnUserInfoByUserID(Integer userId){
        String redisKey;
        redisTemplate.setKeySerializer(new StringRedisSerializer());
//        redisTemplate.setValueSerializer(new Jackson2JsonRedisSerializer<User>(User.class));
//        User user = (User) redisTemplate.opsForValue().get(redisKey);
//        if (user==null){
//            System.out.println("user在redis中查询到");
//            user = userMapper.selectByPrimaryKey(userId);
//            //这里要注意缓存击穿
//            if (user!=null){
//                redisTemplate.opsForValue().set(redisKey,user);
//            }
//        }
        User user =this.queryUserByUserId(userId);
        if (user==null){
            return null;
        }
        String role = user.getRole();
        UserInfo userInfo;
        if ("learner".equalsIgnoreCase(role)){
            redisKey = LEARNER_KEY+user.getUserId();
            redisTemplate.setValueSerializer(new Jackson2JsonRedisSerializer<>(LearnerInfo.class));
            userInfo = (UserInfo) redisTemplate.opsForValue().get(redisKey);
            if (userInfo==null){
                System.out.println("userinfo在redis中查询到");
                userInfo = learnerInfoMapper.selectByPrimaryKey(userId);
                if (userInfo!=null){
                    redisTemplate.opsForValue().set(redisKey,userInfo);
                }
            }
        }else {
            redisKey = EDUCTOR_KEY+user.getUserId();
            redisTemplate.setValueSerializer(new Jackson2JsonRedisSerializer<>(EducatorInfo.class));
            userInfo = (UserInfo) redisTemplate.opsForValue().get(redisKey);
            if (userInfo==null){
                userInfo = educatorInfoMapper.selectByPrimaryKey(userId);
                if (userInfo!=null){
                    redisTemplate.opsForValue().set(redisKey,userInfo);
                }
            }

        }

        List<CourseTeacher> courses = courseService.queryCoursesByUserId(userId,role);
        System.out.println(courses);

        String uniId = user.getUniId();
        University university = universityMapper.selectByPrimaryKey(uniId);
        user.setUserInfo(userInfo);
        user.setUniversity(university);
        if (courses!=null){
            user.setCourses(courses);
        }
        return user;
    }

    @Override
    public User queryUserByUserId(Integer userId){
        String redisKey = KeyUtil.returnUserRedisKeyByUserId(userId);
        redisTemplate.setKeySerializer(new StringRedisSerializer());
        redisTemplate.setValueSerializer(new Jackson2JsonRedisSerializer<User>(User.class));
        User user = (User) redisTemplate.opsForValue().get(redisKey);
        if (user==null){
            System.out.println("user在redis中查询到");
            user = userMapper.selectByPrimaryKey(userId);
            //这里要注意缓存击穿
            if (user!=null){
                redisTemplate.opsForValue().set(redisKey,user);
            }
        }
        return user;
    }

    @Override
    public int changgepassword(User user) {

        return userMapper.updateByPrimaryKeySelective(user);
    }
}
